package com.kool.system.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kool.core.CoreConstants;
import com.kool.core.cache.KCache;
import com.kool.core.exception.AppException;
import com.kool.core.util.StringUtils;
import com.kool.system.bean.SyAutDefBean;
import com.kool.system.bean.SyRoleAutBean;
import com.kool.system.bean.SyRoleBean;
import com.kool.system.bean.SyRoleGroupAutBean;
import com.kool.system.bean.SyRoleGroupBean;
import com.kool.system.bean.SyRoleRoleGroupBean;
import com.kool.system.bean.SyUserInfoBean;
import com.kool.system.bean.io.SYPAGEINFOYBean;
import com.kool.system.bean.vo.PageResult;
import com.kool.system.dao.SyRoleGroupAutDao;
import com.kool.system.dao.SyRoleGroupDao;
import com.kool.system.dao.SyRoleRoleGroupDao;

/**
 * @AUTHOR LUYU
 */
@Service
public class RoleGroupService {
	private static Logger logger = Logger.getLogger(RoleGroupService.class);

	@Autowired
	private SyRoleGroupDao syRoleGroupDao;

	@Autowired
	private SyRoleGroupAutDao syRoleGroupAutDao;

	@Autowired
	private SyRoleRoleGroupDao syRoleRoleGroupDao;

	@Autowired
	private RoleService roleService;

	/**
	 * @DESCRIBE 增加
	 */
	public void add(SyRoleGroupBean syRoleGroup) throws AppException {
		if (null == syRoleGroup) {
			throw new AppException("SY000027");// 输入信息为空
		}
		SyRoleGroupBean group = syRoleGroupDao.selectByPK(syRoleGroup);
		if (group != null) {
			throw new AppException("SY000046");// 角色组编码已经存在
		}
		logger.debug(syRoleGroup.toString());
		syRoleGroupDao.insert(syRoleGroup);
		
		//刷新缓存
		KCache.refresh(CoreConstants.KCACHE_ROLE_GROUP);
	}

	/**
	 * @DESCRIBE 修改
	 */
	public void update(SyRoleGroupBean syRoleGroup) throws AppException {
		if (null == syRoleGroup) {
			throw new AppException("SY000027");// 输入信息为空
		}
		logger.debug(syRoleGroup.toString());
		syRoleGroupDao.update(syRoleGroup);
		
		//刷新缓存
		KCache.refresh(CoreConstants.KCACHE_ROLE_GROUP);
	}

	/**
	 * @DESCRIBE 删除
	 */
	public void delete(SyRoleGroupBean syRoleGroup) throws AppException {
		if (null == syRoleGroup) {
			throw new AppException("SY000027");// 输入信息为空
		}

		String groupCode = syRoleGroup.getSrgGroupCode();
		// 删除角色组角色关联
		SyRoleRoleGroupBean rrgInfo = new SyRoleRoleGroupBean();
		rrgInfo.setSrrGroupCode(groupCode);
		syRoleRoleGroupDao.deletes(rrgInfo);

		// 删除角色组权限关联
		SyRoleGroupAutBean groupAut = new SyRoleGroupAutBean();
		groupAut.setSgaGroupCode(groupCode);
		syRoleGroupAutDao.deletes(groupAut);

		logger.debug(syRoleGroup.toString());
		syRoleGroupDao.delete(syRoleGroup);
		
		//刷新缓存
		KCache.refresh(CoreConstants.KCACHE_ROLE_GROUP);
	}

	/**
	 * @DESCRIBE 分页查询
	 */
	public PageResult queryPage(SyRoleGroupBean syRoleGroup, SYPAGEINFOYBean pageInfo) {
		logger.debug(syRoleGroup.toString());
		int total = syRoleGroupDao.selectTotal(syRoleGroup);

		int currentPage = pageInfo.getCurrentPage();
		int pageSize = pageInfo.getPageSize();
		int offset = (currentPage - 1) * pageSize;
		int pageCount = (total + pageSize - 1) / pageSize;
		List<SyRoleGroupBean> list = syRoleGroupDao.selectPage(syRoleGroup, offset, pageInfo.getPageSize());

		pageInfo.setTotal(total);
		pageInfo.setPageCount(pageCount);

		PageResult pageResult = new PageResult();
		pageResult.setListBusinessValue(new ArrayList<>(list));
		pageResult.setPageInfo(pageInfo);
		return pageResult;
	}

	/**
	 * @DESCRIBE 查询
	 */
	public List<SyRoleGroupBean> query(SyRoleGroupBean syRoleGroup) throws AppException {
		if (null == syRoleGroup) {
			syRoleGroup = new SyRoleGroupBean();
		}

		logger.debug(syRoleGroup.toString());
		return syRoleGroupDao.select(syRoleGroup);
	}

	/**
	 * @DESCRIBE 查询角色组权限
	 * @DATE 2018年7月12日 上午9:55:47
	 *
	 * @param groupCode
	 * @return
	 * @throws AppException
	 */
	public List<SyRoleGroupAutBean> queryGroupAuth(String groupCode) throws AppException {
		if (StringUtils.isEmpty(groupCode)) {
			throw new AppException("SY000035");// 角色组编码为空
		}
		SyRoleGroupAutBean info = new SyRoleGroupAutBean();
		info.setSgaGroupCode(groupCode);
		List<SyRoleGroupAutBean> list = syRoleGroupAutDao.select(info);
		return list;
	}

	/**
	 * 
	 * @DESCRIBE 角色组授权，同时会增量授权角色权限和用户权限
	 * @DATE 2018年7月12日 上午9:59:23
	 *
	 * @param groupCode
	 * @param listIn
	 * @throws AppException
	 */
	public void resetAuth(String groupCode, List<SyRoleGroupAutBean> listIn) throws AppException {
		if (StringUtils.isEmpty(groupCode)) {
			throw new AppException("SY000035");// 角色组编码为空
		}
		SyRoleGroupAutBean info = new SyRoleGroupAutBean();
		info.setSgaGroupCode(groupCode);
		syRoleGroupAutDao.deletes(info);

		SyRoleGroupBean group = (SyRoleGroupBean) KCache.get(CoreConstants.KCACHE_ROLE_GROUP, groupCode);
		if (listIn != null && listIn.size() > 0) {
			for (SyRoleGroupAutBean rga : listIn) {
				SyAutDefBean aut = (SyAutDefBean) KCache.get(CoreConstants.KCACHE_AUT, rga.getSgaAutCode());
				rga.setSgaCmt(
						new StringBuilder().append(group.getSrgName()).append("-").append(aut.getSadName()).toString());
			}
			syRoleGroupAutDao.insertBatch(listIn);
		}

		// 角色组关联角色授权
		// 查询角色列表
		SyRoleRoleGroupBean rrgInfo = new SyRoleRoleGroupBean();
		rrgInfo.setSrrGroupCode(groupCode);
		List<SyRoleRoleGroupBean> listRoles = syRoleRoleGroupDao.select(rrgInfo);
		if (listRoles != null && listRoles.size() > 0) {
			// 对每个角色重新授权
			for (SyRoleRoleGroupBean role : listRoles) {
				String roleCode = role.getSrrRoleCode();
				// 查询角色已有权限
				List<SyRoleAutBean> listRoleAutOld = roleService.queryRoleAuth(roleCode);
				List<SyRoleAutBean> listRoleAut = new ArrayList<>();
				// 新角色权限取已有权限和角色组权限的并集
				listRoleAut.addAll(listRoleAutOld);
				for (SyRoleGroupAutBean groupAut : listIn) {
					String autCode = groupAut.getSgaAutCode();
					if (roleAutContainAut(listRoleAutOld, autCode)) {
						continue;
					}
					SyRoleAutBean roleAut = new SyRoleAutBean();
					roleAut.setSraAutCode(autCode);
					roleAut.setSraRoleCode(roleCode);
					listRoleAut.add(roleAut);
				}
				roleService.resetAuth(roleCode, listRoleAut);
			}
		}

	}

	/**
	 * @DESCRIBE 判断角色已有权限是否包含新授权的权限
	 * @DATE 2018年7月12日 上午10:10:50
	 *
	 * @param listRoleAutOld
	 * @param autCode
	 * @return
	 */
	private boolean roleAutContainAut(List<SyRoleAutBean> listRoleAutOld, String autCode) {
		boolean isContain = false;
		if (null == listRoleAutOld || listRoleAutOld.size() <= 0) {
			isContain = false;
		}
		for (SyRoleAutBean userAut : listRoleAutOld) {
			if (userAut.getSraAutCode().equals(autCode)) {
				isContain = true;
			}
		}
		return isContain;
	}

	/**
	 * @DESCRIBE 根据主键查询一条记录
	 * @DATE 2018年7月12日 上午10:34:54
	 *
	 * @param beanIn
	 * @return
	 * @throws AppException
	 */
	public SyRoleGroupBean queryOne(SyRoleGroupBean pk) throws AppException {
		if (null == pk) {
			throw new AppException("SY000028");// 输入主键为空
		}

		return syRoleGroupDao.selectByPK(pk);
	}

	/**
	 * @DESCRIBE 查询角色组的角色列表
	 * @DATE 2018年7月12日 上午10:36:01
	 *
	 * @param groupCode
	 * @return
	 */
	public List<SyRoleBean> queryRolesOfGroup(String groupCode) {
		List<SyRoleBean> listRoles = new ArrayList<>();
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT B.* FROM SY_ROLE_ROLE_GROUP A, SY_ROLE B ");
		sb.append("WHERE A.SRR_ROLE_CODE=B.SRO_ROLE_CODE ");
		sb.append("AND A.SRR_GROUP_CODE=\"" + groupCode + "\"");
		List<Map<String, Object>> list = syRoleRoleGroupDao.selectBySql(sb.toString());
		if (list != null) {
			for (Map<String, Object> map : list) {
				SyRoleBean user = SyRoleBean.DBResultToBean(map);
				listRoles.add(user);
			}
		}
		return listRoles;
	}

	/**
	 * @DESCRIBE 查询角色组关联的用户列表
	 * @DATE 2018年7月12日 上午10:40:45
	 *
	 * @param groupCode
	 * @return
	 */
	public List<SyUserInfoBean> queryUsersOfGroup(String groupCode) {
		List<SyUserInfoBean> listUsers = new ArrayList<>();
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT C.* FROM SY_ROLE_ROLE_GROUP A,SY_USER_ROLE B, SY_USER_INFO C ");
		sb.append("WHERE A.SRR_ROLE_CODE=B.SUR_ROLE_CODE ");
		sb.append("AND B.SUR_USER_CID=C.SUI_USER_CID ");
		sb.append("AND A.SRR_GROUP_CODE=\"" + groupCode + "\"");
		List<Map<String, Object>> list = syRoleRoleGroupDao.selectBySql(sb.toString());
		if (list != null) {
			for (Map<String, Object> map : list) {
				SyUserInfoBean user = SyUserInfoBean.DBResultToBean(map);
				listUsers.add(user);
			}
		}
		return listUsers;
	}
}
